package br.eng.eliseu.gwt.aconchego.camera.client.ui;

import br.eng.eliseu.gwt.aconchego.camera.client.service.LoginService;
import br.eng.eliseu.gwt.aconchego.camera.client.service.LoginServiceAsync;
import br.eng.eliseu.gwt.aconchego.camera.client.service.UsuarioService;
import br.eng.eliseu.gwt.aconchego.camera.client.service.UsuarioServiceAsync;
import br.eng.eliseu.gwt.aconchego.camera.client.ui.component.EditAsyncCallback;
import br.eng.eliseu.gwt.aconchego.camera.client.ui.usuario.UsuarioEdit;
import br.eng.eliseu.gwt.aconchego.camera.client.ui.usuario.UsuarioList;
import br.eng.eliseu.gwt.aconchego.camera.module.AcessoCam;
import br.eng.eliseu.gwt.aconchego.camera.module.GrupoEnum;
import br.eng.eliseu.gwt.aconchego.camera.shared.PanelUtil;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

public class Home extends Composite {

	interface HomeUiBinder extends UiBinder<Widget, Home> {}
	private static HomeUiBinder uiBinder = GWT.create(HomeUiBinder.class);
	private final LoginServiceAsync loginService = GWT.create(LoginService.class);
	private final UsuarioServiceAsync usuarioService = GWT.create(UsuarioService.class);
	
	@UiField VerticalPanel menuPanel;
	@UiField Hyperlink alteraSenhaLink;
	@UiField Hyperlink usuariosLink;
	@UiField Hyperlink logoutLink;

	@UiField VerticalPanel loginPanel;
	@UiField TextBox emailLoginTBox;
	@UiField PasswordTextBox senhaLoginTBox;
	@UiField Hyperlink esqueceuSenhaLoginHLink;
	@UiField Label msgErroLoginLabel;
	@UiField Button entrarLoginButton;

	@UiField VerticalPanel corpoPanel;
	
	private VideoView video;
	private UsuarioList usuariolist;
	private AlteraSenha alteraSenha;

	private AcessoCam acessoLogin = new AcessoCam();

	public Home() {
		initWidget(uiBinder.createAndBindUi(this));
		loginPanel.getElement().setId("login");
		
		
		PanelUtil.setVisibleAll(corpoPanel, false);
		loginPanel.setVisible(true);
		
		menuPanel.setVisible(false);
		verificaPrimeiroUsuarioAsync();
	}
	
	@UiHandler("alteraSenhaLink")
	void onAlteraSenhaLinkClick(ClickEvent event) {
		PanelUtil.setVisibleAll(corpoPanel, false);

		alteraSenha = new AlteraSenha(acessoLogin);
		corpoPanel.add(alteraSenha);
		alteraSenha.setCallback(new EditAsyncCallback<AcessoCam>() {

			public void onOk(AcessoCam retorno) {
				corpoPanel.remove(alteraSenha);
				video.setVisible(true);
			}

			public void onCancel() {
				corpoPanel.remove(alteraSenha);
				video.setVisible(true);
			}
		});
	}

	@UiHandler("usuariosLink")
	void onUsuariosLinkClick(ClickEvent event) {
		PanelUtil.setVisibleAll(corpoPanel, false);

		usuariolist = new UsuarioList(acessoLogin);
		corpoPanel.add(usuariolist);
		usuariolist.setCallback( new EditAsyncCallback<AcessoCam>() {

			public void onOk(AcessoCam acesso) {
				corpoPanel.remove(usuariolist);
				video.setVisible(true);
			}

			public void onCancel() {
				corpoPanel.remove(usuariolist);
				video.setVisible(true);
			}

		} );
	}

	@UiHandler("logoutLink")
	void onLogoutLinkClick(ClickEvent event) {
		corpoPanel.clear();
		menuPanel.setVisible(false);
		loginPanel.setVisible(true);
		senhaLoginTBox.setValue("");
		
	}

	@UiHandler("esqueceuSenhaLoginHLink")
	void onEsqueceuSenhaLoginHLinkClick(ClickEvent event) {
		corpoPanel.clear();
		if( emailLoginTBox == null || "".equals(emailLoginTBox.getValue())){
			showErroLogin("Informe seu e-Mail de acesso");
			return;
		}

		
		usuarioService.enviaSenha( emailLoginTBox.getValue(), new AsyncCallback<Boolean>(){

			public void onSuccess(Boolean arg0) {
				Window.alert("Sua nova senha foi enviada para o seu email!!");
				
			}
			
			public void onFailure(Throwable erro) {
				Window.alert(erro.getMessage());
			}

		});
	}

	@UiHandler("entrarLoginButton")
	void onEntrarLoginButtonClick(ClickEvent event) {
		if (checaCampoEmBrancoLogin()){
			loginAsync();
		}
	}
	
	private void loginAsync(){
		loginService.login( emailLoginTBox.getValue(), senhaLoginTBox.getValue(), new AsyncCallback<AcessoCam>() {

			public void onSuccess(AcessoCam acesso) {
				loginPanel.setVisible(false);
				menuPanel.setVisible(true);
				usuariosLink.setVisible(acesso.getGrupo().equals(GrupoEnum.ADMINISTRADOR));
				video = new VideoView(acesso);
				corpoPanel.clear();
				corpoPanel.add(video);
				acessoLogin = acesso;

			}

			public void onFailure(Throwable erro) {
				showErroLogin(erro.getMessage());
			}
			
		});
	}
	
	private Boolean checaCampoEmBrancoLogin(){
		showErroLogin("");
		
		if( emailLoginTBox == null || "".equals(emailLoginTBox.getValue())){
			showErroLogin("Informe seu e-Mail de acesso");
			return false;
		}
		
		if( senhaLoginTBox == null || "".equals(senhaLoginTBox.getValue())){
			showErroLogin("Informe sua S" +
					"enha de acesso");
			return false;
		}
		
		return true;
	}
	
	private void verificaPrimeiroUsuarioAsync(){
		
		loginService.contaUsuarios( new AsyncCallback<Number>(){

			public void onSuccess(Number nroUsuarios) {
				if( nroUsuarios.equals(0) ){
					// --- Se ainda nao tiver usuario cadastrado abre a tela de cadastro de usuario
					loginPanel.setVisible(false);
					
					final UsuarioEdit usuarioEdit = new UsuarioEdit(new AcessoCam());
					usuarioEdit.setAcesso(new AcessoCam());
					corpoPanel.add(usuarioEdit);
					usuarioEdit.setCallback( new EditAsyncCallback<AcessoCam>() {

						public void onOk(AcessoCam ac) {
							corpoPanel.remove(usuarioEdit);
							loginPanel.setVisible(true);
							emailLoginTBox.setValue(ac.getUsuario().getEmail());
						}

						public void onCancel() {
							corpoPanel.remove(usuarioEdit);
							loginPanel.setVisible(true);
						}

					} );
					
				}
			}
			
			public void onFailure(Throwable erro) {
			}


		});
	}
	
	
	private void showErroLogin(String msg) {
		msgErroLoginLabel.setText(msg);
	}
}
